package com.come4loves.game.module.card.handler;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.come4loves.core.comunicate.protocol.Response;
import com.come4loves.core.comunicate.router.annotation.Cmd;
import com.come4loves.core.result.BytesResult;
import com.come4loves.core.result.Result;
import com.come4loves.core.result.TResult;
import com.come4loves.game.constent.GameStatusCodeConstant;
import com.come4loves.game.dbproxy.entity.CardGroup;
import com.come4loves.game.module.battle.helper.PBConvertHelper;
import com.come4loves.game.module.card.dao.CardGroupDao;
import com.come4loves.game.module.card.facade.CardFacade;
import com.come4loves.game.module.card.facade.CardGroupFacade;
import com.come4loves.game.module.card.model.CardGroupModel;
import com.come4loves.game.module.card.model.CardModel;
import com.come4loves.game.proto.CardCmd;
import com.come4loves.game.proto.CardProto;
import com.come4loves.game.proto.CardProto.CardGroupOperationModel;
import com.come4loves.game.proto.CardProto.CardGroupResponse;
import com.come4loves.game.proto.CardProto.CardWarehouseResponse;
import com.come4loves.game.proto.ModuleName;
import com.come4loves.game.server.router.GatewayRouterHandlerImpl;
import com.come4loves.game.server.session.PlayerContext;

import io.netty.channel.ChannelHandlerContext;

@Controller
public class CardHandler extends GatewayRouterHandlerImpl {
	
	@Autowired
	public CardFacade cardFacade;
	
	@Autowired
	public CardGroupFacade cardGroupFacade;
	
	@Autowired
	public CardGroupDao cardGroupDao;
	
	@Autowired
	private PlayerContext playerContext;
	@Override
	public byte getModule() {
		return ModuleName.Module.CARD_VALUE;
	}

	
	@Cmd(id = CardCmd.Card.CARD_WAREHOUSE_VALUE)
	public BytesResult getCardWarehouse(ChannelHandlerContext context,byte[] bytes, Response response) {
		long actorId = playerContext.getActorId(context);
		CardWarehouseResponse.Builder protoResponse = CardWarehouseResponse.newBuilder();
		
		TResult<List<CardModel>> collectionCard = cardFacade.getCollectionCard(actorId);
		if (collectionCard.isOk()) {
			for (CardModel cardModel : collectionCard.item) {
				CardProto.CardModel.Builder cardBuidler = CardProto.CardModel.newBuilder();
				cardBuidler.setCfgId(cardModel.cfgId);
				cardBuidler.setCount(cardModel.count);
				cardBuidler.setLevel(cardModel.level);
				cardBuidler.setPriority(cardModel.priority);
				cardBuidler.setType(PBConvertHelper.cardTypeConvert(cardModel.type));
				protoResponse.addCards(cardBuidler);
			}
		} else {
			return BytesResult.valueOf(collectionCard.statusCode);
		}
		
		TResult<Collection<CardGroupModel>> cardGroupList = cardGroupFacade.getCardGroupList(actorId);
		if (cardGroupList.isOk()) {
			for (CardGroupModel groupModel : cardGroupList.item) {
				CardProto.CardGroupViewModel.Builder cardGroupBuidler = CardProto.CardGroupViewModel.newBuilder();
				cardGroupBuidler.setId(groupModel.groupId);
				cardGroupBuidler.setName(groupModel.name);
				cardGroupBuidler.setGroupFlag(groupModel.groupFlag);
				CardModel mainGeneral = groupModel.getMainGeneral();
				if (mainGeneral != null) {
					cardGroupBuidler.setMainGen(mainGeneral.cfgId);
				} else {
					cardGroupBuidler.setMainGen(0);
				}
				cardGroupBuidler.setCardNumber(groupModel.getCardsNum());
				protoResponse.addGroupView(cardGroupBuidler);
			}
		} else {
			return BytesResult.valueOf(cardGroupList.statusCode);
		}
		return BytesResult.sucess(protoResponse.build().toByteArray());
	}
	
	
	@Cmd(id = CardCmd.Card.CARD_GROUP_INFO_VALUE)
	public BytesResult getCardGroupInfo(ChannelHandlerContext context,byte[] bytes, Response response) throws Exception {
		long actorId = playerContext.getActorId(context);
		CardProto.CardGroupRequest request = CardProto.CardGroupRequest.parseFrom(bytes);
		
		CardGroup cardGroup = cardGroupDao.getCardGroup(actorId);
		if (cardGroup.isContainsKeyModel(request.getGroupId())) {
			CardGroupResponse.Builder protoResponse = CardGroupResponse.newBuilder();
			CardProto.CardGroupModel.Builder gBuilder = CardProto.CardGroupModel.newBuilder();
			CardGroupModel convert = cardGroup.getGroupModel(request.getGroupId());
			gBuilder.setId(convert.groupId);
			gBuilder.setName(convert.name);
			gBuilder.setGroupFlag(convert.groupFlag);
			for (CardModel model : convert.cardList) {
				gBuilder.addCards(CardModel.convert(model));
			}
			protoResponse.setModel(gBuilder);
			
			return BytesResult.sucess(protoResponse.build().toByteArray());
		} else {
			return BytesResult.valueOf(GameStatusCodeConstant.CARD_GROUP_NOT_EXIST);
		}
	}
	
	@Cmd(id = CardCmd.Card.CARD_ADD_DEL_2_GROUP_VALUE)
	public BytesResult addOrDeleteCardOnGroup(ChannelHandlerContext context,byte[] bytes, Response response) throws Exception {
		long actorId = playerContext.getActorId(context);
		
		CardProto.CardAddOrDel2GroupRequest request = CardProto.CardAddOrDel2GroupRequest.parseFrom(bytes);
		ArrayList<CardGroupOperationModel> delList = new ArrayList<>(request.getDeleteCardsList());
		ArrayList<CardGroupOperationModel> addList = new ArrayList<>(request.getAddCardsList());
		Result addOrDelCard2Group = cardGroupFacade.addOrDelCard2Group(actorId, request.getGroupId(), delList, addList);
		if (addOrDelCard2Group.isOk()) {
			return BytesResult.sucess();
		} else {
			return BytesResult.valueOf(addOrDelCard2Group.statusCode);
		}
	}
	
	
	@Cmd(id = CardCmd.Card.CARD_GROUP_ADD_VALUE)
	public BytesResult addCardGroup(ChannelHandlerContext context,byte[] bytes, Response response) throws Exception {
		long actorId = playerContext.getActorId(context);
		CardProto.CardGroupAddRequest request = CardProto.CardGroupAddRequest.parseFrom(bytes);
		List<CardProto.CardModel> cardsList = request.getCardsList();
		List<CardModel> modelList = new ArrayList<CardModel>();
		for (CardProto.CardModel cardModel : cardsList) {
			modelList.add(CardModel.valueOf(cardModel.getCfgId(), cardModel.getLevel(), PBConvertHelper.cardTypeReverse(cardModel.getType()), 1, cardModel.getPriority()));
		}
		TResult<CardGroupModel> createNewCardGroup = cardGroupFacade.createNewCardGroup(actorId, (byte)request.getFlag(), request.getName(), modelList);
		
		if (createNewCardGroup.isOk()) {
//			CardGroupModel cardGroupModel = createNewCardGroup.item;
//			CardProto.CardGroupListResponse.Builder builder = CardProto.CardGroupListResponse.newBuilder();
//			CardProto.CardGroupViewModel.Builder modelBuilder = CardProto.CardGroupViewModel.newBuilder();
//			modelBuilder.setName(cardGroupModel.name);
//			builder.setModel(createNewCardGroup.item);
			return BytesResult.sucess();
		} else {
			return BytesResult.valueOf(createNewCardGroup.statusCode);
		}
	}
	
	
	@Cmd(id = CardCmd.Card.CARD_GROUP_DELETE_VALUE)
	public BytesResult deleteCardGroup(ChannelHandlerContext context,byte[] bytes, Response response) throws Exception {
		long actorId = playerContext.getActorId(context);
		CardProto.CardGroupDeleteRequest request = CardProto.CardGroupDeleteRequest.parseFrom(bytes);
		Result deleteCardGroup = cardGroupFacade.deleteCardGroup(actorId, request.getGroupId());
		
		if (deleteCardGroup.isOk()) {
			return BytesResult.sucess();
		} else {
			return BytesResult.valueOf(deleteCardGroup.statusCode);
		}
	}
	
	
	@Cmd(id = CardCmd.Card.CARD_GROUP_RENAME_VALUE)
	public BytesResult renameCardGroup(ChannelHandlerContext context,byte[] bytes, Response response) throws Exception {
		long actorId = playerContext.getActorId(context);
		CardProto.CardGroupRenameRequest request = CardProto.CardGroupRenameRequest.parseFrom(bytes);
		Result renameGroup = cardGroupFacade.renameCardGroup(actorId, request.getGroupId(), request.getName());
		
		if (renameGroup.isOk()) {
			return BytesResult.sucess();
		} else {
			return BytesResult.valueOf(renameGroup.statusCode);
		}
	}
	
	
	
	
	@Cmd(id = CardCmd.Card.CARD_MODIFY_PRIORITY_VALUE)
	public BytesResult modifyCardPriority(ChannelHandlerContext context,byte[] bytes, Response response) throws Exception {
		long actorId = playerContext.getActorId(context);
		
		CardProto.CardModifyPriorityRequest request = CardProto.CardModifyPriorityRequest.parseFrom(bytes);
		Result modify = cardFacade.modifyCardPriority(actorId, PBConvertHelper.cardTypeReverse(request.getType()), request.getCfgId(), request.getPriority());
		
		if (modify.isOk()) {
			return BytesResult.sucess();
		} else {
			return BytesResult.valueOf(modify.statusCode);
		}
	}
	
	
	@Cmd(id = CardCmd.Card.CARD_GROUP_LIST_VALUE)
	public BytesResult listCardGroup(ChannelHandlerContext context,byte[] bytes, Response response) {
		long actorId = playerContext.getActorId(context);
		TResult<Collection<CardGroupModel>> cardGroupList = cardGroupFacade.getCardGroupList(actorId);
		
		if (cardGroupList.isOk()) {
			CardProto.CardGroupListResponse.Builder builder = CardProto.CardGroupListResponse.newBuilder();
			for (CardGroupModel groupModel : cardGroupList.item) {
				CardProto.CardGroupViewModel.Builder cardGroupBuidler = CardProto.CardGroupViewModel.newBuilder();
				cardGroupBuidler.setId(groupModel.groupId);
				cardGroupBuidler.setName(groupModel.name);
				cardGroupBuidler.setGroupFlag(groupModel.groupFlag);
				CardModel mainGeneral = groupModel.getMainGeneral();
				if (mainGeneral != null) {
					cardGroupBuidler.setMainGen(mainGeneral.cfgId);
				} else {
					cardGroupBuidler.setMainGen(0);
				}
				cardGroupBuidler.setCardNumber(groupModel.getCardsNum());
				builder.addGroupView(cardGroupBuidler);
			}
			return BytesResult.sucess(builder.build().toByteArray());
		} else {
			return BytesResult.valueOf(cardGroupList.statusCode);
		}
	}
	
	
}
